/**
 * 自定义select组件
 * by zhangxinyue
 * create 2020-08-29
 * modify 2021-07-14 1.添加tooltip提示；2.多选时，选项置顶
 */
import React, { Component } from 'react';
import _ from 'lodash';
import PropTypes from 'prop-types';
import { QuestionCircleOutlined } from '@ant-design/icons';
import { Select, Tooltip, Form } from 'antd';
import { FormItemLayout, NoLableLayout } from '../formPub';
import styles from './index.less';

const { Option, OptGroup } = Select;
const trueFalseData = [
  { title: '否', value: '0' },
  { title: '是', value: '1' },
];

class SelectC extends Component {
  // props默认值
  static defaultProps = {
    title: '', // 下拉框名称，默认为空（无名称）
    helper: '', // 下拉框提示信息，默认无提示信息
    allowClear: false, // 是否展示“删除”按钮，默认不展示
    placeholder: '请选择', // 占位符，默认为“请选择”
    onChange: () => {}, // 选择内容变化时的回调，默认不执行回调
    loading: false, // 等待状态，默认为非等待状态
    dataSource: [], // 下拉框数据源，默认无数据
    showSearch: true, // 单选模式下可搜索
    onRef: () => {}, // 本组件的引用
    formItemLayout: FormItemLayout, // 布局
    rules: [], // 校验规则
    selectWidth: '', // 输入框长度
    disabled: false, // 默认启用
    isMultiple: false, // 默认单选
    maxTagCount: 0, // 默认多选时显示一个标签，多余的缩率
    filterOption: true, // 默认根据输入项对现有下拉选项进行筛选
    optionTitle: false, // 默认不悬浮显示option选项的title
    labalWrap: false, // 默认title不换行
    isTrueFalseJudge: false, // 如果下拉框中只有是否的选择 可以使用这个属性为true，不需要传入dataSource
    rightContent: null, // 右侧的内容
    rightBtnWrapStyle: {}, // 右侧的按钮的样式
    isGroup: false, // 是否以分组展示
    defaultActiveFirstOption: true, // 是否回填第一项，默认是
    positionBody: false, //  下拉框，默认跟随，如果select父节点有滚动，下拉框被遮挡，则需要设置为true
    colon: false, // 冒号  默认不显示
    getPopupContainer: () => {}, // 菜单渲染父节点。默认渲染到 body 上
    rightContentSpacing: null, // 右侧多个按钮之间的间距
  };

  constructor(props) {
    super(props);

    this.state = {
      tooltipInfo: '', // 鼠标移动到组件，展示当前选中项全称
      dataSource: this.props.dataSource,
      initialValue: this.props.initialValue,
    };
  }

  componentDidMount() {
    // 父组件对本组件的引用
    this.props.onRef(this);
    if (this.props.initialValue != undefined && this.props.initialValue != null) {
      this.setTooltip(this.props.initialValue);
    }
  }

  componentDidUpdate(prevProps) {
    const getValue = prevProps.form?.getFieldsValue();
    const ds = prevProps.dataSource && prevProps.dataSource.length > 0 ? JSON.stringify(prevProps.dataSource) : '';
    const dsN = this.props.dataSource && this.props.dataSource.length > 0 ? JSON.stringify(this.props.dataSource) : '';
    const init = this.props.isMultiple ? (prevProps.initialValue && prevProps.initialValue.length > 0 ? JSON.stringify(prevProps.initialValue) : '') : prevProps.initialValue;
    const initN = this.props.isMultiple ? (this.props.initialValue && this.props.initialValue.length > 0 ? JSON.stringify(this.props.initialValue) : '') : this.props.initialValue;
    if (ds !== dsN || init !== initN) {
      // 下拉数据源更新 保存表单数据
      if (ds !== dsN && getValue && getValue[prevProps.dataIndex]) {
        this.setSelect(getValue[prevProps.dataIndex]);
        this.setTooltip(getValue[prevProps.dataIndex]);
      } else {
        this.setTooltip(this.props.initialValue, this.props);
        this.setSelect(this.props.initialValue);
      }
    }
  }

  // 非初始化状态下更改下拉选项(供父组件调用)
  setSelect = (value) => {
    const { isMultiple } = this.props;
    const valueF = {};
    if (isMultiple) {
      valueF[this.props.dataIndex] = value instanceof Array ? value : [];
    } else {
      valueF[this.props.dataIndex] = value ? value.toString() : '';
    }
    this.props.form?.setFieldsValue(valueF);
    this.setTooltip(value);
  };

  // 设置tooltip
  setTooltip = (e, propT = this.props) => {
    const { dataSource, isMultiple, isGroup } = propT;
    let data = dataSource;
    let tooltipInfo = '';
    if (isGroup) {
      // 分组状态下
      const tempData = [];
      data.forEach((labels) => {
        labels.list.forEach((item) => tempData.push(item));
      });
      data = [...tempData];
    }
    if (e != undefined && e != null) {
      if (Array.isArray(e) && isMultiple) {
        // 多选
        e.forEach((element, index) => {
          const find = data.filter((item) => item.value == element);
          if (find && find.length > 0) {
            tooltipInfo += find[0].title;
          }
          // 最后一个元素之后不用换行
          if (index != e.length - 1) {
            tooltipInfo += '\r\n';
          }
        });
      } else {
        // 单选
        const find = data.filter((item) => e == item.value);
        if (find && find.length > 0) {
          tooltipInfo += find[0].title;
        }
      }
    }
    this.setState({
      tooltipInfo: tooltipInfo == '' ? '' : <div style={{ whiteSpace: 'pre' }}>{tooltipInfo}</div>,
    });
    return tooltipInfo == '' ? '' : <div style={{ whiteSpace: 'pre' }}>{tooltipInfo}</div>;
  };

  // 响应下拉变更事件
  onChange = (e, option) => {
    this.props.onChange(e, option);
    this.setTooltip(e);
  };

  // 右侧内容点击效果
  rightBtnHandleClick = () => {
    this.props.rightContentClick && this.props.rightContentClick();
  };

  render() {
    const {
      notFoundContent,
      rightBtnWrapStyle,
      rightContent,
      styleRow,
      title,
      dataIndex,
      initialValue,
      helper,
      allowClear,
      placeholder,
      loading,
      dropdownMatchSelectWidth,
      dropdownStyle,
      showSearch,
      dataSource,
      positionBody,
      style,
      isMultiple,
      maxTagCount,
      formItemLayout,
      onSearch,
      filterOption,
      optionTitle,
      isTrueFalseJudge,
      labalWrap,
      isGroup,
      rules,
      defaultActiveFirstOption,
      colon,
      rightContentSpacing,
    } = this.props;
    if (dataIndex === 'target2') {
    }
    const initvalue = Array.isArray(initialValue) ? initialValue : initialValue ? initialValue.toString() : initialValue;
    return (
      <Form.Item key={initvalue}>
        <div className={rightContent ? `${styles.rightContentBtn} ${styles.btnWrap}` : styles.rightContentBtn}>
          <div style={{ width: '100%' }}>
            {rightContent && (
              <Form.Item label={<div style={{ visibility: 'hidden' }}>xxx</div>} labelCol={formItemLayout.labelCol} wrapperCol={formItemLayout.wrapperCol}>
                {rightContent.length > 0 &&
                  rightContent.map((item, index) => {
                    const { length } = rightContent;
                    return (
                      // eslint-disable-next-line react/jsx-key
                      <div
                        className={styles.rightBtnWrap}
                        style={{
                          ...rightBtnWrapStyle,
                          right: length > 1 ? `${index * rightContentSpacing + index * 30}px` : '0px',
                        }}
                        onClick={() => {
                          this.rightBtnHandleClick(item, index);
                        }}
                      >
                        {item}
                      </div>
                    );
                  })}
              </Form.Item>
            )}
            <Tooltip title={this.state.tooltipInfo}>
              <Form.Item
                colon={colon}
                name={dataIndex}
                initialValue={initvalue}
                rules={rules}
                getValueFromEvent={this.props.getValueFromEvent}
                className={labalWrap ? 'labalWrap' : ''}
                labelCol={title ? formItemLayout.labelCol : NoLableLayout.labelCol}
                wrapperCol={title ? formItemLayout.wrapperCol : NoLableLayout.wrapperCol}
                style={style}
                label={
                  title ? (
                    helper ? (
                      <span>
                        {title}&nbsp;
                        <Tooltip title={helper}>
                          <QuestionCircleOutlined />
                        </Tooltip>
                      </span>
                    ) : (
                      <span>{title}</span>
                    )
                  ) : undefined
                }
              >
                <Select
                  getPopupContainer={(triggerNode) => (!positionBody ? triggerNode.parentNode : document.body)}
                  notFoundContent={notFoundContent}
                  maxTagCount={maxTagCount}
                  maxTagPlaceholder={(omittedValues) => `共选择${omittedValues.length}项`}
                  mode={isMultiple && 'multiple'}
                  allowClear={allowClear}
                  placeholder={placeholder}
                  defaultActiveFirstOption={defaultActiveFirstOption}
                  onChange={this.onChange}
                  onSearch={onSearch}
                  loading={loading}
                  filterOption={filterOption}
                  dropdownMatchSelectWidth={dropdownMatchSelectWidth} // 下拉菜单和选择器同宽
                  dropdownStyle={dropdownStyle} // 下拉菜单的 style 属性（object类型）
                  showSearch={showSearch} // 使单选模式可搜索
                  style={
                    styleRow
                      ? styleRow
                      : {
                          width: this.props.selectWidth
                            ? this.props.selectWidth
                            : rightContent
                            ? rightContent.length > 1
                              ? `calc(100% - ${rightContent.length * 30 + rightContent.length * rightContentSpacing}px)`
                              : `calc(100% - 30px)`
                            : '100%',
                        }
                  }
                  disabled={this.props.disabled}
                >
                  {
                    // 不设置disabled时，默认disabled值为false
                    !isGroup ? (
                      isTrueFalseJudge ? (
                        trueFalseData.map((item) => (
                          <Option title={optionTitle ? item.title : ''} value={item.value} key={item.value} disabled={item.disabled === undefined ? false : item.disabled}>
                            {item.title}
                          </Option>
                        ))
                      ) : loading ? (
                        <Option key={'blank'} value={'blank'} disabled={true}>
                          正在加载中...
                        </Option>
                      ) : dataSource ? (
                        dataSource.map((item) => (
                          <Option title={optionTitle ? item.title : ''} value={item.value} key={item.value} disabled={item.disabled === undefined ? false : item.disabled}>
                            {item.title}
                          </Option>
                        ))
                      ) : (
                        ''
                      )
                    ) : loading ? (
                      <Option key={'blank'} value={'blank'} disabled={true}>
                        正在加载中...
                      </Option>
                    ) : dataSource ? (
                      dataSource.map((labels, index) => {
                        const optionList = labels.list || [];
                        return (
                          <OptGroup label={labels.label} key={index}>
                            {optionList.map((item) => (
                              <Option title={optionTitle ? item.title : ''} value={item.value} key={item.value} disabled={item.disabled === undefined ? false : item.disabled}>
                                {item.title}
                              </Option>
                            ))}
                          </OptGroup>
                        );
                      })
                    ) : (
                      ''
                    )
                  }
                </Select>
              </Form.Item>
            </Tooltip>
          </div>
        </div>
      </Form.Item>
      // <Form.Item key={initvalue}>
      //   <div className={rightContent ? `${styles.rightContentBtn} ${styles.btnWrap}` : styles.rightContentBtn}>
      //     <div style={{ width: '100%' }}>
      //       {rightContent && (
      //         <Form.Item label={<div style={{ visibility: 'hidden' }}>xxx</div>} labelCol={formItemLayout.labelCol} wrapperCol={formItemLayout.wrapperCol}>
      //           <div className={styles.rightBtnWrap} style={rightBtnWrapStyle ? rightBtnWrapStyle : null} onClick={this.rightBtnHandleClick}>
      //             {rightContent}
      //           </div>
      //         </Form.Item>
      //       )}
      //       <Tooltip title={this.state.tooltipInfo}>
      //         <Form.Item
      //           colon={colon}
      //           name={dataIndex}
      //           initialValue={initvalue}
      //           rules={rules}
      //           getValueFromEvent={this.props.getValueFromEvent}
      //           className={labalWrap ? 'labalWrap' : ''}
      //           labelCol={title ? formItemLayout.labelCol : NoLableLayout.labelCol}
      //           wrapperCol={title ? formItemLayout.wrapperCol : NoLableLayout.wrapperCol}
      //           style={style}
      //           label={
      //             title ? (
      //               helper ? (
      //                 <span>
      //                   {title}&nbsp;
      //                   <Tooltip title={helper}>
      //                     <QuestionCircleOutlined />
      //                   </Tooltip>
      //                 </span>
      //               ) : (
      //                 <span>{title}</span>
      //               )
      //             ) : undefined
      //           }
      //         >
      //           <Select
      //             getPopupContainer={(triggerNode) => (!positionBody ? triggerNode.parentNode : document.body)}
      //             notFoundContent={notFoundContent}
      //             maxTagCount={maxTagCount}
      //             maxTagPlaceholder={(omittedValues) => `共选择${omittedValues.length}项`}
      //             mode={isMultiple && 'multiple'}
      //             allowClear={allowClear}
      //             placeholder={placeholder}
      //             defaultActiveFirstOption={defaultActiveFirstOption}
      //             onChange={this.onChange}
      //             onSearch={onSearch}
      //             loading={loading}
      //             filterOption={filterOption}
      //             dropdownMatchSelectWidth={dropdownMatchSelectWidth} // 下拉菜单和选择器同宽
      //             dropdownStyle={dropdownStyle} // 下拉菜单的 style 属性（object类型）
      //             showSearch={showSearch} // 使单选模式可搜索
      //             style={styleRow ? styleRow : { width: this.props.selectWidth ? this.props.selectWidth : rightContent ? `calc(100% - 30px)` : '100%' }}
      //             disabled={this.props.disabled}
      //           >
      //             {
      //               // 不设置disabled时，默认disabled值为false
      //               !isGroup ? (
      //                 isTrueFalseJudge ? (
      //                   trueFalseData.map((item) => (
      //                     <Option title={optionTitle ? item.title : ''} value={item.value} key={item.value} disabled={item.disabled === undefined ? false : item.disabled}>
      //                       {item.title}
      //                     </Option>
      //                   ))
      //                 ) : loading ? (
      //                   <Option key={'blank'} value={'blank'} disabled={true}>
      //                     正在加载中...
      //                   </Option>
      //                 ) : dataSource ? (
      //                   dataSource.map((item) => (
      //                     <Option title={optionTitle ? item.title : ''} value={item.value} key={item.value} disabled={item.disabled === undefined ? false : item.disabled}>
      //                       {item.title}
      //                     </Option>
      //                   ))
      //                 ) : (
      //                   ''
      //                 )
      //               ) : loading ? (
      //                 <Option key={'blank'} value={'blank'} disabled={true}>
      //                   正在加载中...
      //                 </Option>
      //               ) : dataSource ? (
      //                 dataSource.map((labels, index) => {
      //                   const optionList = labels.list || [];
      //                   return (
      //                     <OptGroup label={labels.label} key={index}>
      //                       {optionList.map((item) => (
      //                         <Option title={optionTitle ? item.title : ''} value={item.value} key={item.value} disabled={item.disabled === undefined ? false : item.disabled}>
      //                           {item.title}
      //                         </Option>
      //                       ))}
      //                     </OptGroup>
      //                   );
      //                 })
      //               ) : (
      //                 ''
      //               )
      //             }
      //           </Select>
      //         </Form.Item>
      //       </Tooltip>
      //     </div>
      //   </div>
      // </Form.Item>
    );
  }
}

// props类型
SelectC.propsTypes = {
  form: PropTypes.object, // form对象
  title: PropTypes.string, // 显示名称
  dataIndex: PropTypes.string, // Form识别的Item ID
  initialValue: PropTypes.oneOfType([
    // 初始值
    PropTypes.string,
    PropTypes.number,
    PropTypes.array,
  ]),
  helper: PropTypes.oneOfType([
    // 提示帮助信息
    PropTypes.string,
    PropTypes.element,
  ]),
  allowClear: PropTypes.bool, // 支持清除
  labalWrap: PropTypes.bool, // 支持标题换行
  placeholder: PropTypes.string, // 占位符
  onChange: PropTypes.func, // 输入框选中改变回调
  onSearch: PropTypes.func, // 输入框内容变化时的回调
  loading: PropTypes.bool, // 加载中状态(当displayData为空时该状态才有效)
  dataSource: PropTypes.array, // 数据源 {[value:value,title:title],[],...},若有禁用情况，设置disabled为true，默认不禁用
  dropdownMatchSelectWidth: PropTypes.bool, // 下拉菜单和选择器同宽
  dropdownStyle: PropTypes.object, // 下拉菜单的 style 属性
  showSearch: PropTypes.bool, // 使单选模式可搜索
  style: PropTypes.object, // 样式
  onRef: PropTypes.func, // 本组件的引用（可用来父组件调用内部方法）
  rules: PropTypes.array, // 校验规则
  formItemLayout: PropTypes.object, // 布局
  selectWidth: PropTypes.string, // 输入框长度
  disabled: PropTypes.bool, // 是否禁用
  isMultiple: PropTypes.bool, // 是否多选
  maxTagCount: PropTypes.number, // 多选时，可以最多显示多少tag（isMultiple为true时有效）
  filterOption: PropTypes.oneOfType([
    // 是否根据输入项对现有下拉选项进行筛选，也可以传入函数当其为一个函数时，会接收 inputValue option 两个参数，当 option 符合筛选条件时，应返回 true，反之则返回 false
    PropTypes.bool,
    PropTypes.func,
  ]),
  optionTitle: PropTypes.bool, // 是否需要显示选中该 Option 后，Select 的 title
  isGroup: PropTypes.bool, // 是否以分组形式展示
  positionBody: PropTypes.bool, //  下拉框默认跟随，如果select父节点有滚动，下拉框被遮挡，则需要设置为true
  colon: PropTypes.bool, // 冒号  默认不显示
  getPopupContainer: PropTypes.func, // 菜单渲染父节点。默认渲染到 body 上
  rightContent: PropTypes.array, // 右侧按钮  索引为0的是最右边，依次往右排列
  rightContentSpacing: PropTypes.number, // 右侧多个按钮之间的间距
};

export default SelectC;
